﻿#region Usings

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Xml.XPath;
using Yandex.Market.Api.Common;
using Yandex.Market.Api.YmlSerialization;

#endregion

namespace Yandex.Market.Api.Model
{
    /// <summary>
    ///   Описание tour
    /// </summary>
    [YmlSerializeAs("offer")]
    [Serializable]
    public class OfferTour : OfferBase
    {
        /// <summary>
        /// 
        /// </summary>
        public OfferTour()
        {}

        internal OfferTour(IOffer offer) : base(offer)
        {}

        /// <summary>
        /// 
        /// </summary>
        [YmlAttributeForClass]
        [YmlSerializeAs("type")]
        [YmlAttributeOrder(10)]
        public YmlOfferType OfferType
        {
            get { return YmlOfferType.Tour; }
        }

        /// <summary>
        ///   Часть света. Необязательный элемент.
        /// </summary>
        [YmlSerializeAs("worldRegion")]
        [YmlElementOrder(200)]
        public string WorldRegion { get; set; }

        /// <summary>
        ///   Страна. Необязательный элемент.
        /// </summary>
        [YmlSerializeAs("country")]
        [YmlElementOrder(210)]
        public string Country { get; set; }

        /// <summary>
        ///   Курорт или город. Необязательный элемент.
        /// </summary>
        [YmlSerializeAs("region")]
        [YmlElementOrder(220)]
        public string Region { get; set; }

        /// <summary>
        ///   Количество дней тура. Обязательный элемент.
        /// </summary>
        [YmlSerializeAs("days")]
        [YmlElementOrder(230)]
        public uint Days { get; set; }

        /// <summary>
        ///   Даты заездов. Необязательный элемент.
        /// </summary>
        [YmlCollection(YmlCollectionSerializationTypes.RecursiveWithNoContainingElement, EachElementName = "dataTour")]
        [YmlFormat("dd/MM/yy")]
        [YmlElementOrder(240)]
        public List<DateTime> DataTour { get; set; }

        /// <summary>
        ///   Название отеля (в некоторых случаях название тура). Oбязательный элемент.
        /// </summary>
        [YmlSerializeAs("name")]
        [YmlElementOrder(250)]
        public string Name { get; set; }

        /// <summary>
        ///   Звезды отеля. Необязательный элемент.
        /// </summary>
        [YmlSerializeAs("hotel_stars")]
        [YmlElementOrder(260)]
        public string HotelStars { get; set; }

        /// <summary>
        ///   Тип комнаты (SNG, DBL, ...). Необязательный элемент.
        /// </summary>
        [YmlSerializeAs("room")]
        [YmlElementOrder(270)]
        public string Room { get; set; }

        /// <summary>
        ///   Тип питания (All, HB, ...). Необязательный элемент.
        /// </summary>
        [YmlSerializeAs("meal")]
        [YmlElementOrder(280)]
        public string Meal { get; set; }

        /// <summary>
        ///   Что включено в стоимость тура. Обязательный элемент.
        /// </summary>
        [YmlSerializeAs("included")]
        [YmlElementOrder(290)]
        public string Included { get; set; }

        /// <summary>
        ///   Транспорт. Обязательный элемент.
        /// </summary>
        [YmlSerializeAs("transport")]
        [YmlElementOrder(300)]
        public string Transport { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [YmlSerializeAs("price_min")]
        [YmlFormat("0.##")]
        [YmlElementOrder(310)]
        public double? PriceMin { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [YmlSerializeAs("price_max")]
        [YmlFormat("0.##")]
        [YmlElementOrder(320)]
        public double? PriceMax { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [YmlSerializeAs("options")]
        [YmlElementOrder(330)]
        public string Options { get; set; }

        internal static OfferTour CreateOfferTourFromXml(XPathNavigator nav, IOffer dummyOffer)
        {
            OfferTour offer = new OfferTour(dummyOffer);
            uint uintVal;
            XPathNavigator node = nav.SelectSingleNode("worldRegion");
            if(node != null)
                offer.WorldRegion = node.Value;

            node = nav.SelectSingleNode("country");
            if(node != null)
                offer.Country = node.Value;

            node = nav.SelectSingleNode("region");
            if(node != null)
                offer.Region = node.Value;

            node = nav.SelectSingleNode("days");
            if(node != null && uint.TryParse(node.Value, out uintVal))
                offer.Days = uintVal;

            XPathNodeIterator iterator = nav.Select("dataTour");
            if(iterator.Count > 0)
            {
                offer.DataTour = new List<DateTime>();
                while(iterator.MoveNext())
                {
                    if(iterator.Current != null)
                    {
                        string strDate = iterator.Current.Value;
                        DateTime date;
                        if(!string.IsNullOrEmpty(strDate)
                           &&
                           DateTime.TryParseExact(strDate,
                                                  "dd/MM/yy",
                                                  CultureInfo.InvariantCulture,
                                                  DateTimeStyles.None,
                                                  out date))
                            offer.DataTour.Add(date);
                    }
                }
            }

            node = nav.SelectSingleNode("name");
            if(node != null)
                offer.Name = node.Value;

            node = nav.SelectSingleNode("hotel_stars");
            if(node != null)
                offer.HotelStars = node.Value;

            node = nav.SelectSingleNode("room");
            if(node != null)
                offer.Room = node.Value;

            node = nav.SelectSingleNode("meal");
            if(node != null)
                offer.Meal = node.Value;

            node = nav.SelectSingleNode("included");
            if(node != null)
                offer.Included = node.Value;

            node = nav.SelectSingleNode("transport");
            if(node != null)
                offer.Transport = node.Value;

            double doubleVal;
            node = nav.SelectSingleNode("price_min");
            if(node != null && Utils.TryParseYmlDouble(node.Value, out doubleVal))
                offer.PriceMin = doubleVal;

            node = nav.SelectSingleNode("price_max");
            if(node != null && Utils.TryParseYmlDouble(node.Value, out doubleVal))
                offer.PriceMax = doubleVal;

            node = nav.SelectSingleNode("options");
            if(node != null)
                offer.Options = node.Value;

            return offer;
        }
    }
}